package com.lottery.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.concurrent.TimeUnit;

/**
 * 奖品发放服务
 * 负责处理奖品发放的核心逻辑
 */
@Service
@Slf4j
public class AwardService {
    
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    @Autowired
    private StringRedisTemplate redisTemplate;
    
    private static final String AWARD_LOCK_KEY = "award:lock:";
    
    private boolean testMode = false;
    
    /**
     * 发放奖品
     * 包含了幂等性检查、库存检查、分布式锁等机制
     *
     * @param userId 用户ID
     * @param awardId 奖品ID
     * @return 是否发放成功
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean grantAward(String userId, String awardId) {
        if (testMode) {
            return false;  // 测试模式下模拟失败
        }
        // 使用Redis分布式锁防止并发
        String lockKey = AWARD_LOCK_KEY + userId + ":" + awardId;
        boolean locked = redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 10, TimeUnit.SECONDS);
        if (!locked) {
            throw new RuntimeException("操作太频繁，请稍后重试");
        }
        
        try {
            // 检查是否重复发奖
            if (isAwardGranted(userId, awardId)) {
                return false;
            }
            
            // 检查库存
            if (!checkAndDeductStock(awardId)) {
                return false;
            }
            
            // 记录发奖
            saveAwardRecord(userId, awardId);
            
            return true;
        } finally {
            redisTemplate.delete(lockKey);
        }
    }
    
    /**
     * 检查是否已经发过奖
     */
    private boolean isAwardGranted(String userId, String awardId) {
        Integer count = jdbcTemplate.queryForObject(
            "SELECT COUNT(*) FROM award_record WHERE user_id = ? AND award_id = ? AND state = 1",
            Integer.class, userId, awardId);
        return count != null && count > 0;
    }
    
    /**
     * 检查并扣减库存
     */
    private boolean checkAndDeductStock(String awardId) {
        int updated = jdbcTemplate.update(
            "UPDATE strategy_detail SET award_surplus_count = award_surplus_count - 1 " +
            "WHERE award_id = ? AND award_surplus_count > 0",
            awardId);
        return updated > 0;
    }
    
    /**
     * 保存发奖记录
     */
    private void saveAwardRecord(String userId, String awardId) {
        jdbcTemplate.update(
            "INSERT INTO award_record(user_id, award_id, state) VALUES(?, ?, 1)",
            userId, awardId);
    }
    
    // 用于测试的方法
    public void setTestMode(boolean testMode) {
        this.testMode = testMode;
    }
} 